<template>
  <div class="container">
    <div class="search">
      <el-input v-model="params.username" placeholder="请输入用户名" clearable></el-input>
      <el-select v-model="params.singerType" placeholder="角色">
        <el-option value="0" label="普通用户"></el-option>
        <el-option value="1" label="歌手"></el-option>
      </el-select>
      <el-select v-model="params.status" placeholder="用户状态" clearable>
        <el-option value="0" label="正常"></el-option>
        <el-option value="1" label="封禁"></el-option>
      </el-select>
      <el-input v-model="params.other" placeholder="模糊查询"></el-input>
      <el-button type="primary" @click="findBySearch">搜索</el-button>
      <el-button type="warning" @click="clearParams">清空</el-button>
      <el-button type="success" @click="addConsumer">新增</el-button>
    </div>
    <div class="table">
      <el-table :data="consumerData" stripe highlight-current-row style="width: 100%" height="75vh">
        <el-table-column fixed label="序号" prop="id" sortable width="80"></el-table-column>
        <el-table-column fixed label="用户名" prop="username" width="110"></el-table-column>
        <el-table-column label="UID" prop="uid" width="130">
          <template #default="{ row }"
            ><el-tag>{{ row.uid }}</el-tag></template
          >
        </el-table-column>
        <el-table-column label="角色" prop="singerType" width="100">
          <!-- 0:普通用户 1:歌手 -->
          <template #default="{ row }">
            <el-tag v-if="row.singerType === '0'" type="success">普通用户</el-tag>
            <el-tag v-else>歌手</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="性别" prop="sex" width="70">
          <template #default="{ row }">
            <!-- 女：0  男：1 -->
            <el-tag v-if="row.sex === '0'" type="danger">女</el-tag>
            <el-tag v-else-if="row.sex === '1'" type="success">男</el-tag>
            <el-tag v-else type="info">未知</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="头像" prop="avatar" width="100">
          <template #default="{ row }">
            <el-image
              style="width: 70px; height: 70px; border-radius: 50%"
              :src="'http://localhost:8080/api/files/' + row.avatar"
              :preview-src-list="['http://localhost:8080/api/files/' + row.avatar]"
            ></el-image>
          </template>
        </el-table-column>
        <el-table-column label="手机号" prop="phone" width="150"></el-table-column>
        <el-table-column label="邮箱" prop="email" width="180"></el-table-column>
        <el-table-column label="出生日期" prop="birth" width="150"></el-table-column>
        <el-table-column label="介绍" prop="introduction" width="150"></el-table-column>
        <el-table-column label="地址" prop="address" width="180"></el-table-column>
        <el-table-column label="积分" prop="point" width="120"></el-table-column>
        <el-table-column label="登录时间" prop="loginTime" width="180"></el-table-column>
        <el-table-column label="创建时间" prop="createTime" width="180"></el-table-column>
        <el-table-column fixed="right" label="账号状态" prop="sts" width="100">
          <template #default="{ row }">
            <el-switch v-model="row.sts" @change="updateStatus(row)"></el-switch>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="200">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="editConsumer(row)">编辑</el-button>
            <el-button type="success" size="small" @click="downLoad(row)">下载</el-button>
            <el-popconfirm
              title="你确定删除吗？"
              confirm-button-text="确定"
              cancel-button-text="取消"
              @confirm="deleteConsumer(row)"
            >
              <template #reference>
                <el-button type="danger" size="small">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pagination">
      <el-pagination
        v-model:current-page="params.pageNum"
        v-model:page-size="params.pageSize"
        :page-sizes="[5, 10, 15, 20]"
        size="default"
        layout="total, sizes, prev, pager, next, jumper"
        :total="params.total"
        @size-change="findBySearch"
        @current-change="findBySearch"
      />
    </div>
    <div class="dialog">
      <!-- 新增or修改 -->
      <el-dialog
        v-model="dialogFormVisible"
        :title="dialogFormData.id || dialogFormData.id === 0 ? '修改用户' : '添加用户'"
        width="30%"
        top="1vh"
        @close="cancel"
      >
        <el-form :model="dialogFormData">
          <el-form-item prop="uid" label="UID" label-width="20%">
            <el-tag>{{ dialogFormData.uid }}</el-tag>
          </el-form-item>
          <el-form-item prop="username" label="用户名" label-width="20%">
            <el-input v-model="dialogFormData.username" clearable></el-input>
          </el-form-item>
          <el-form-item prop="singerType" label="角色" label-width="20%">
            <el-select v-model="dialogFormData.singerType" placeholder="请选择" clearable>
              <el-option label="普通用户" value="0"></el-option>
              <el-option label="歌手" value="1"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item prop="sex" label="性别" label-width="20%">
            <el-radio-group v-model="dialogFormData.sex">
              <el-radio value="1">男</el-radio>
              <el-radio value="0">女</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="phone" label="手机号" label-width="20%">
            <el-input v-model="dialogFormData.phone" clearable></el-input>
          </el-form-item>
          <el-form-item prop="email" label="邮箱" label-width="20%">
            <el-input v-model="dialogFormData.email" clearable></el-input>
          </el-form-item>
          <el-form-item prop="birth" label="出生日期" label-width="20%">
            <el-date-picker v-model="dialogFormData.birth" style="width: 90%" type="date" placeholder="选择日期" clearable />
          </el-form-item>
          <el-form-item prop="introduction" label="介绍" label-width="20%">
            <el-input v-model="dialogFormData.introduction" style="width: 90%" type="textarea" rows="3"></el-input>
          </el-form-item>

          <!-- 级联地址 -->
          <el-form-item prop="address" label="地址" label-width="20%">
            <el-tag style="width: 90%; margin-bottom: 7px">{{ dialogFormData.address }}</el-tag>
            <el-cascader
              v-model="dialogFormData.addressId"
              style="width: 90%"
              :options="addressData"
              :props="{ expandTrigger: 'hover' }"
              clearable
              @change="handleAddress"
            ></el-cascader>
          </el-form-item>

          <!-- TODO:文件上传 -->
          <el-form-item label="头像" label-width="20%">
            <!-- <el-upload action="http://localhost:8080/api/files/upload" list-type="picture-card" :auto-upload="true"
              :on-success="successUpload" limit="1">
              <i-ep-plus />
              <template #file="{ file }">
                <div>
                  <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
                  <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-preview" @click="handlePicturePreview(file),file.url=''">
                      <i-ep-zoom-in />
                    </span>
                    TODO:为啥要删除两次才能删除成功
                    因为有两个图片：一是upload默认的图片展示，二是自定义的图片展示
                    <span class="el-upload-list__item-delete" @click="handleRemove(file)">
                      <i-ep-delete />
                    </span>
                  </span>
                </div>
              </template>
            </el-upload> -->

            <!-- <el-upload action="http://localhost:8080/api/files/upload" list-type="picture-card" :auto-upload="true"
              :on-success="successUpload" :on-preview="handlePicturePreview" :on-remove="handleRemove" limit="1">
              <template #default><img v-if="dialogFormData.avatar" :src="dialogFormData.avatar" alt="头像" style="width: 100%;">
                <i-ep-plus />
              </template>
            </el-upload> -->

            <el-upload
              action="http://localhost:8080/api/files/upload"
              list-type="picture-card"
              :auto-upload="true"
              :limit="1"
              :on-success="successUpload"
              :on-remove="handleRemove"
              :on-preview="handlePicturePreview"
              :file-list="avatarList"
              :class="{ 'none-up': uploadDisabled }"
            >
              <!-- TODO:disabled禁用之后可能会导致前边图像的小图标隐藏【如删除图标】:disabled="uploadDisabled" -->
              <i-ep-plus />
            </el-upload>
          </el-form-item>

          <el-form-item prop="point" label="积分" label-width="20%">
            <el-input v-model="dialogFormData.point" clearable></el-input>
          </el-form-item>
          <el-form-item prop="status" label="账号状态" label-width="20%">
            <el-radio-group v-model="dialogFormData.status">
              <el-radio value="0">正常</el-radio>
              <el-radio value="1">封禁</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="cancel">取消</el-button>
            <el-button type="primary" @click="submit"> 确定 </el-button>
          </div>
        </template>
      </el-dialog>
      <!-- 头像预览 -->
      <el-dialog v-model="preImgVisible" width="600" align-center>
        <img :src="avatarUrl" alt="头像预览" style="width: 100%" />
      </el-dialog>
    </div>
  </div>
</template>

<script setup lang="ts">
import { addressFindAllApi, addressFindById } from '@/api/address'
import { consumerDeleteApi, consumerFindBySearchApi, consumerSaveApi } from '@/api/consumer'
import { ElMessage } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'

// 控制弹窗的隐藏与显示
const dialogFormVisible = ref(false)
// 头像预览的显示与隐藏
const preImgVisible = ref(false)
// 头像路径
const avatarUrl = ref()
// 控制上传头像是否隐藏
const uploadDisabled = ref(false)
// 上传的头像列表
const avatarList: any = ref([])
// 用户信息
const consumerData = ref([])
const params = reactive({
  username: '',
  pageNum: 1,
  pageSize: 5,
  total: '',
  singerType: '',
  status: '',
  other: '', //模糊查询
  sts: '', //自添加：用于状态开关switch
})
// 地址信息
const addressData = ref()
// 弹窗表单信息
const dialogFormData = ref({
  id: '',
  uid: '',
  username: '',
  singerType: '',
  sex: '',
  phone: '',
  email: '',
  birth: '',
  introduction: '',
  address: '',
  point: '',
  status: '',
  avatar: '',
  addressId: [], //地址级联Id
})
onMounted(async () => {
  findBySearch()
  // 初始化级联地址信息
  let res = await addressFindAllApi()
  addressData.value = res.data
})

// 条件查询
const findBySearch = async () => {
  let res = await consumerFindBySearchApi(params)
  consumerData.value = res.data.list.map((item: any) => ({
    ...item,
    sts: item.status === '0',
  }))

  params.total = res.data.total
}
// 清空
const clearParams = () => {
  Object.assign(params, {
    username: '',
    // pageNum: 1,
    // pageSize: 5,
    // total: '',
    singerType: '',
    status: '',
    other: '',
  })
  // 重新渲染页面
  findBySearch()
}
// 删除
const deleteConsumer = async (row: any) => {
  await consumerDeleteApi(row.id)
  ElMessage.success('删除成功')
  // 重新渲染
  findBySearch()
}
// 修改账号状态
const updateStatus = async (row: any) => {
  row.status = row.status === '0' ? '1' : '0'
  await consumerSaveApi(row)
  ElMessage.success('修改状态成功')
}
// 新增用户
const addConsumer = () => {
  // 清空弹窗表单信息
  clearDialogFormData()
  // // 修改动态类
  // uploadDisabled.value = false
  // 清除头像信息
  // avatarList.value = []
  // TODO:这里还是会看见一瞬间的上一次的头像信息
  // 显示弹窗
  dialogFormVisible.value = true
}
// 编辑用户
const editConsumer = (row: any) => {
  Object.assign(dialogFormData.value, row)
  dialogFormVisible.value = true
  console.log('编辑用户row:', row)

  // avatarList.value.push('http://localhost:8080/api/files/' + row.avatar)
  // avatarList.value = ['http://localhost:8080/api/files/' + row.avatar]
  // const temp = [{ name: row.avatar, url: 'http://localhost:8080/api/files/' + row.avatar }]
  if (row.avatar) {
    avatarList.value = [{ name: row.avatar, url: 'http://localhost:8080/api/files/' + row.avatar }]
  }
  uploadDisabled.value = avatarList.value.length >= 1
}
// 图像文件上传成功
const successUpload = (res: any, file: any, fileList: any) => {
  avatarList.value = fileList
  uploadDisabled.value = avatarList.value.length >= 1 //禁用
  dialogFormData.value.avatar = res.data
}
// 预览头像
const handlePicturePreview = (file: any) => {
  avatarUrl.value = file.url
  preImgVisible.value = true
}
// 删除头像
const handleRemove = (file: any, fileList: any) => {
  let index = avatarList.value.findIndex((item: any) => {
    return item.uid === file.uid
  })
  avatarList.value.splice(index, 1) //删除
  uploadDisabled.value = avatarList.value.length >= 1
  dialogFormData.value.avatar = ''
}
// 将级联地址id转换为地址信息
const handleAddress = async () => {
  dialogFormData.value.address = ''
  if (dialogFormData.value.addressId) {
    for (let i = 0; i < dialogFormData.value.addressId.length; i++) {
      let res = await addressFindById(dialogFormData.value.addressId[i])
      dialogFormData.value.address += res.data + '/'
    }
  }
}
// 清空弹窗表单信息
const clearDialogFormData = () => {
  Object.assign(dialogFormData.value, {
    id: '',
    uid: '',
    username: '',
    singerType: '',
    sex: '',
    phone: '',
    email: '',
    birth: '',
    introduction: '',
    address: '',
    point: '',
    status: '',
    avatar: '',
    addressId: [],
  })
}
// 弹窗关闭
const cancel = () => {
  // 关闭弹窗
  dialogFormVisible.value = false
  // 清除头像信息
  avatarList.value = []
  // 修改动态类
  uploadDisabled.value = false
}
// 新增or修改
const submit = async () => {
  // 去除没有属性值的属性
  Object.keys(dialogFormData.value).forEach((key) => {
    const value = dialogFormData.value[key as keyof typeof dialogFormData.value]
    if (value === '' || value === null || value === undefined) {
      delete dialogFormData.value[key as keyof typeof dialogFormData.value]
    }
  })
  await consumerSaveApi(dialogFormData.value)
  dialogFormVisible.value = false
  ElMessage.success(dialogFormData.value.id || dialogFormData.value.id === 0 ? '修改成功' : '添加成功')
  findBySearch()
}
// 下载头像图片
const downLoad = (row: any) => {
  if (row.avatar?.includes('|')) {
    location.href = 'http://localhost:8080/api/files/' + row.avatar
  } else {
    ElMessage.warning('无可下载资源')
  }
}
</script>

<style scoped lang="scss">
.container {
  .search {
    display: flex;
    flex-wrap: nowrap;

    .el-input {
      width: 200px;
      margin-right: 10px;
    }

    .el-select {
      width: 100px;
      margin-right: 10px;
    }
  }

  .table {
    margin: 15px 0;

    .el-switch {
      --el-switch-on-color: #13ce66;
      --el-switch-off-color: #ff4949;
    }
  }

  .pagination {
    display: flex;
    justify-content: center;
  }

  .dialog {
    .el-input,
    .el-select {
      width: 90%;
    }
  }
}

/* CSS */
.cell {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
// 深度选择器
.none-up ::v-deep(.el-upload--picture-card) {
  display: none;
}
</style>
